﻿@using System.Diagnostics.CodeAnalysis
@using Gurux.DLMS.AMI.Shared.DIs;
@using Gurux.DLMS.AMI.Shared.DTOs;
@using Gurux.DLMS.AMI.Shared.Rest;
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

@inject HttpClient Http
@inject IGXNotifier Notifier
@inject NavigationManager NavigationManager;
@implements IDisposable
@if (!_hide)
{
    @ChildContent
    @if (Checked)
    {
        <Tooltip Style="position: absolute; left:0;" Title="Remove from favorites">
            <span @onclick="Unselect" style="color:deepskyblue"><h2>&#9733;</h2></span>
        </Tooltip>
    }
    else
    {
        <Tooltip Style="position: absolute; left:0;" Title="Add to favorites">
            <span @onclick="Select" style="color:black"><h2>&#9734;</h2></span>
        </Tooltip>
    }
}
@code {
    /// <summary>
    /// User favorites.
    /// </summary>
    List<GXFavorite> _favorites = new List<GXFavorite>();

    [Parameter]
    public RenderFragment? ChildContent { get; set; }

    public bool Checked { get; set; }

    /// <summary>
    /// Select the star.
    /// </summary>
    async Task Select()
    {
        try
        {
            Checked = true;
            StateHasChanged();
            Notifier.ProgressStart();
            Notifier.ClearStatus();
            //Add favorite.
            UpdateFavorite req = new UpdateFavorite();
            req.Favorites = new GXFavorite[]
            {
                new GXFavorite()
                {
                    Path = NavigationManager.ToBaseRelativePath(NavigationManager.Uri)
                }
            };
            var ret = await Http.PostAsJson<UpdateFavoriteResponse>("api/Favorite/Add", req);
            if (ret.Ids == null || !ret.Ids.Any())
            {
                //If object is not create yet.
                Checked = false;
                StateHasChanged();
            }
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
        finally
        {
            Notifier?.ProgressEnd();
        }
    }

    /// <summary>
    /// Unselect the star.
    /// </summary>
    async Task Unselect()
    {
        try
        {
            Checked = false;
            StateHasChanged();
            Notifier.ProgressStart();
            Notifier.ClearStatus();
            string path = NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
            foreach (var it in _favorites)
            {
                if (it.Path == path)
                {
                    //Remove favorite.
                    _favorites.Remove(it);
                    RemoveFavorite req = new RemoveFavorite();
                    req.Ids = new Guid[] { it.Id };
                    _ = await Http.PostAsJson<RemoveFavoriteResponse>("api/Favorite/Delete", req);
                    break;
                }
            }
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
        finally
        {
            Notifier?.ProgressEnd();
        }
    }

    bool _hide;

    /// <summary>
    /// Update check state.
    /// </summary>
    private void OnLocationChanged(object? sender, LocationChangedEventArgs e)
    {
        bool found = false;
        string path = NavigationManager.ToBaseRelativePath(e.Location);
        //Favorite title is not shown on the main page or favorites page.
        bool oldHide = _hide;
        _hide = string.IsNullOrEmpty(path) || string.Compare(path, "Favorites", true) == 0;
        if (!_hide)
        {
            foreach (var it in _favorites)
            {
                if (it.Path == path)
                {
                    found = true;
                    break;
                }
            }

        }
        if (oldHide != _hide || Checked != found)
        {
            Checked = found;
            StateHasChanged();
        }
    }

    protected override async Task OnInitializedAsync()
    {
        try
        {
            Notifier.ProgressStart();
            Notifier.ClearStatus();
            Notifier.Clear();
            NavigationManager.LocationChanged += OnLocationChanged;

            Notifier.On<IEnumerable<GXFavorite>>(this, nameof(IGXHubEvents.FavoriteUpdate), (favorites) =>
            {
                foreach (var it in favorites)
                {
                    //Remove old item and add the updated one.
                    var item = _favorites.Where(w => w.Id == it.Id).SingleOrDefault();
                    if (item != null)
                    {
                        _favorites.Remove(item);
                    }
                    _favorites.Add(it);
                }
            });
            Notifier.On<IEnumerable<GXFavorite>>(this, nameof(IGXHubEvents.FavoriteDelete), (favorites) =>
            {
                foreach (var it in favorites)
                {
                    var item = _favorites.Where(w => w.Id == it.Id).SingleOrDefault();
                    if (item != null)
                    {
                        _favorites.Remove(item);
                    }
                }
            });
            //Get favorites.
            ListFavorites req = new ListFavorites();
            var tmp = await Http.PostAsJson<ListFavoritesResponse>("api/Favorite/List", req);
            if (tmp?.Favorites != null)
            {
                _favorites.AddRange(tmp.Favorites);
                StateHasChanged();
            }
            //Update favorite star.
            OnLocationChanged(null, new LocationChangedEventArgs(NavigationManager.Uri, false));
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
        finally
        {
            Notifier?.ProgressEnd();
        }
    }

    public void Dispose()
    {
        NavigationManager.LocationChanged -= OnLocationChanged;
    }
}